package com.example.zwx.myapplication;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import com.example.zwx.myapplication.Callback.OnBleSendListener;
import com.example.zwx.myapplication.Callback.OnBleStatusChangedListener;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zwx on 16-1-24.
 */
public class BleManager {

    public static final String TAG = BleManager.class.getSimpleName();
    private static final long SCAN_PERIOD = 10000;//扫描10秒
    private Context mContext;
    private boolean autoConnect = true;

    private List<OnBleSendListener> mBleSendCallbacks;

    private ServiceInitListener mServiceInitListener;

    private OnBleStatusChangedListener mOnBleStatusChangedListener;

    private Messenger mServiceMessenger;
    private Messenger mClientMessenger;
    private Handler mClientHandler;

    private BluetoothAdapter mBluetoothAdapter;
    private boolean isScanning;

    private BleManager(Context context) {
        this.mContext = context;
    }

    private static BleManager instance;

    public static BleManager getInstance(Context context) {
        if (instance == null) {
            synchronized (BleManager.class) {
                if (instance == null) {
                    instance = new BleManager(context);
                }
            }
        }
        return instance;
    }

    /**
     * 初始化并连接蓝牙后台服务
     *
     * @param listener ServiceConnection result callback
     */
    @Deprecated
    @TargetApi(18)
    public void init(ServiceInitListener listener) {

        if (listener != null) {
            mServiceInitListener = listener;
        }

        if (mContext == null) {
            Log.e(TAG, "初始化失败，context为null！");
            if (mServiceInitListener != null) {
                mServiceInitListener.onResult(false, "初始化失败，context为null！");
            }
            return;
        }
        if (!BleUtil.isSupportBle(mContext)) {
            Log.e(TAG, "当前设备不支持BLE通讯！");
            if (mServiceInitListener != null) {
                mServiceInitListener.onResult(false, "当前设备不支持BLE通讯！");
            }
            return;
        }


        final BluetoothManager bluetoothManager =
                (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // Checks if Bluetooth is supported on the device.
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "bluetooth is not supported on this device");
            if (mServiceInitListener != null) {
                mServiceInitListener.onResult(false, "初始化失败，当前设备不支持BLE蓝牙通讯");
            }
            return;
        } else if (!mBluetoothAdapter.isEnabled()) {
            //开启蓝牙
            mBluetoothAdapter.enable();
        }


        Intent serviceIntent = new Intent(mContext, BleServiceV2.class);
        mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);


        mClientHandler = new ClientHandler();
        mClientMessenger = new Messenger(new ClientHandler());
    }

    /**
     * 初始化Ble服务
     *
     * @param listener    初始化结果回调
     * @param autoConnect 是否自动连接已绑定的ble外设
     */
    public void init(OnBleStatusChangedListener listener, boolean autoConnect) {
        this.autoConnect = autoConnect;
        if (listener != null) {
            mOnBleStatusChangedListener = listener;
        }
        if (mContext == null) {
            Log.e(TAG, "初始化失败，context为null！");
            if (mOnBleStatusChangedListener != null) {
                mOnBleStatusChangedListener.onInitFailed(OnBleStatusChangedListener.BLE_INIT_FAILED
                        , "初始化失败，context为null！");
            }
            return;
        }
        if (!BleUtil.isSupportBle(mContext)) {
            Log.e(TAG, "当前设备不支持BLE通讯！");
            if (mOnBleStatusChangedListener != null) {
                mOnBleStatusChangedListener.onInitFailed(
                        OnBleStatusChangedListener.BLE_FEATURE_UNAVALIBALE
                        , "当前设备不支持BLE通讯！");
            }

            return;
        }


        final BluetoothManager bluetoothManager =
                (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // Checks if Bluetooth is supported on the device.
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "bluetooth is not supported on this device");
            if (mOnBleStatusChangedListener != null) {
                mOnBleStatusChangedListener.onInitFailed(
                        OnBleStatusChangedListener.BLE_FEATURE_UNAVALIBALE
                        , "当前设备不支持BLE通讯！");
            }
            return;
        } else if (!mBluetoothAdapter.isEnabled()) {
            //开启蓝牙
            mBluetoothAdapter.enable();
        }


        Intent serviceIntent = new Intent(mContext, BleServiceV2.class);
        mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);


        mClientHandler = new ClientHandler();
        mClientMessenger = new Messenger(new ClientHandler());

        if (mOnBleStatusChangedListener != null) {
            mOnBleStatusChangedListener.onInitSuccess();
        }

    }

    public void registOnBleSendFeedbackListener(OnBleSendListener listener) {
        if (mBleSendCallbacks == null) {
            mBleSendCallbacks = new ArrayList<>();
        }
        if (!mBleSendCallbacks.contains(listener)) {
            mBleSendCallbacks.add(listener);
        }
    }

    public void removeOnBleSendFeedbackListener(OnBleSendListener listener) {
        if (mBleSendCallbacks != null && !mBleSendCallbacks.isEmpty()) {
            if (mBleSendCallbacks.contains(listener)) {
                mBleSendCallbacks.remove(listener);
            }
        }
    }

    private void notifyBleSendBack(BleIRData bleIRData) {
        if (mBleSendCallbacks != null && !mBleSendCallbacks.isEmpty()) {
            for (OnBleSendListener listener : mBleSendCallbacks) {
                listener.onResult(bleIRData);
            }
        }
    }

    public void connect2BondedDevice() {
        Message bindMsg = Message.obtain();
        bindMsg.what = BleServiceV2.MSG_CONNECT2_BLE_DEVICE;
        try {
            mServiceMessenger.send(bindMsg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void sendIr(final List<String> irDatas) {
//        new Thread() {
//            @Override
//            public void run() {
//                BleIRData bleIRData = new BleIRData(BleIRData.MODE_LIST);
//                bleIRData.setIrDataList(irDatas);
//                bleIRData.setTimeStamp(System.currentTimeMillis());
//                sendIr(bleIRData);
//            }
//        }.start();

        BleIRData bleIRData = new BleIRData(BleIRData.MODE_LIST);
        if (SimpleRemoteActivity.parseModeSelf) {
            bleIRData.setParseMode(BleIRData.PARSE_MODE_SELF);
        } else {
            bleIRData.setParseMode(BleIRData.PARSE_MODE_VENDOR);
        }
        bleIRData.setIrDataList(irDatas);
        bleIRData.setTimeStamp(System.currentTimeMillis());
        sendIr(bleIRData);


    }

    public void sendIr(BleIRData bleIRData) {
        Message bleMsg = Message.obtain();
        bleMsg.what = BleServiceV2.MSG_SEND_IR_DATA;
        bleMsg.obj = bleIRData;
        try {
            mServiceMessenger.send(bleMsg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    @TargetApi(18)
    public void scanLeDevice(final boolean enable) {
        if (enable) {
            mClientHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    isScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);
            isScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            isScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }

    public void scanLeDevice(boolean enable, final BluetoothAdapter.LeScanCallback callback) {
        if (enable) {
            mClientHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    isScanning = false;
                    mBluetoothAdapter.stopLeScan(callback);
                }
            }, SCAN_PERIOD);
            isScanning = true;
            mBluetoothAdapter.startLeScan(callback);
        } else {
            isScanning = false;
            mBluetoothAdapter.stopLeScan(callback);
        }
    }

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {

        }
    };


    private class ClientHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case BleServiceV2.MSG_DEVICE_CONNECTION_RESULT:
                    /**
                     * 设备连接结果
                     */
                    if (mOnBleStatusChangedListener != null) {
                        boolean isConnected = (boolean) msg.obj;
                        if (isConnected) {
                            mOnBleStatusChangedListener.onDeviceConnected();
                        } else {
                            mOnBleStatusChangedListener.onDeviceDisconnected();
                        }
                    }

                    break;
                case BleServiceV2.MSG_IR_SEND_FEEDBACK:
                    BleIRData bleIRData = (BleIRData) msg.obj;
                    notifyBleSendBack(bleIRData);
                    break;

                case BleServiceV2.MSG_GATT_CONNECTED:
                    if (mOnBleStatusChangedListener != null) {
                        mOnBleStatusChangedListener.onDeviceConnected();
                    }
                    break;
                case BleServiceV2.MSG_GATT_DISCONNECTED:
                    if (mOnBleStatusChangedListener != null) {
                        mOnBleStatusChangedListener.onDeviceDisconnected();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            mServiceMessenger = new Messenger(service);
            Message bindMsg = Message.obtain();
            bindMsg.what = BleServiceV2.MSG_SERVICE_CONNECTED;
            bindMsg.replyTo = mClientMessenger;
            try {
                mServiceMessenger.send(bindMsg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            if (mServiceInitListener != null) {
                mServiceInitListener.onResult(true, "蓝牙后台服务连接成功！");
                AppMsg.showToast(mContext, "蓝牙后台服务连接成功！");
            }

            if (mOnBleStatusChangedListener != null) {
                mOnBleStatusChangedListener.onBleServiceBinded();
            }

            if (autoConnect) {
                connect2BondedDevice();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (mServiceInitListener != null) {
                mServiceInitListener.onResult(false, "蓝牙后台服务连接中断！");
                AppMsg.showToast(mContext, "蓝牙后台服务连接中断！");
            }
        }
    };

    public void destory() {
        try {
            mContext.unbindService(mServiceConnection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化服务连接并打开蓝牙设备回调
     */
    @Deprecated
    public interface ServiceInitListener {
        void onResult(boolean result, String msg);
    }

}
